package com.lixinlei.security.api.config;

import java.util.Optional;

import com.lixinlei.security.api.interceptor.AclInterceptor;
import com.lixinlei.security.api.interceptor.AuditLogInterceptor;
import com.lixinlei.security.api.vo.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
// 这个注解和 @EntityListeners(AuditingEntityListener.class) 没有的话，@CreatedBy 就不知道把谁注入到其标注的属性中
@EnableJpaAuditing
public class SecurityConfig implements WebMvcConfigurer {

    @Autowired
    private AuditLogInterceptor auditLogInterceptor;

    @Autowired
    private AclInterceptor aclInterceptor;

    /**
     * 先添加的拦截器先生效
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(auditLogInterceptor);
        registry.addInterceptor(aclInterceptor);
    }

    /**
     * 这个 Bean 是用来让 @CreatedBy 知道是谁修改了数据
     * @CreatedBy 标注的属性的类型是 String，这里 AuditorAware 的泛型就用 String
     * @return
     */
    @Bean
    public AuditorAware<String> auditorAware() {
        return new AuditorAware<String>() {
            @Override
            public Optional<String> getCurrentAuditor() {
                ServletRequestAttributes servletRequestAttributes
                        = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
                UserInfo info = (UserInfo)servletRequestAttributes.getRequest().getSession().getAttribute("user");
                String username = null;
                if(info != null) {
                    username = info.getUsername();
                }
                return Optional.ofNullable(username);
            }
        };
    }

}

